﻿namespace Tsingda.CacheModule
{
    using System;
    using System.Collections;
    using System.Text.RegularExpressions;
    using System.Web;
    using System.Web.Caching;

    /// <summary>
    /// 以内存的方式提供缓存服务
    /// </summary>
    public class CSCache : ICache
    {
        private  readonly Cache _cache;
        private  int _minutes = 1; //缓存时间的基数值


      public  CSCache()
        {
            System.Web.HttpContext current = System.Web.HttpContext.Current;
            if (current != null)
            {
                _cache = current.Cache;
            }
            else
            {
                _cache = System.Web.HttpRuntime.Cache;
            }
        }

      public CSCache(int cacheFactor)
      {
          _minutes = cacheFactor;
          System.Web.HttpContext current = System.Web.HttpContext.Current;
          if (current != null)
          {
              _cache = current.Cache;
          }
          else
          {
              _cache = System.Web.HttpRuntime.Cache;
          }
      }

      #region 接口方法
      public  bool Container(string key)
      {
          if (null != _cache[key])
              return true;
          else
              return false;
      }

      public  void Add(string key, object memo,int minutes)
      {
          Insert(key, memo, minutes);
      }


      /// <summary>
      /// 清除缓存中指字键值的项
      /// </summary>
      /// <param name="key">键值</param>
      public  void Remove(string key)
      {
          _cache.Remove(key);
      }

      /// <summary>
      /// 根据Key值获取缓存中内容,若不存在,则返回默认字符串 
      /// </summary>
      /// <param name="key"></param>
      /// <returns></returns>
      public  object Get(string key)
      {
          if (null != _cache[key])
              return _cache[key] + "<!-- From CSCache{" + key + "} -->";
          else
              return "no content for this url from CacheHttpModule!";
      }
     
      public void Write(System.Web.HttpApplication application,string key)
      {
          application.Context.Response.Write(Get(key));
      }

        /// <summary>
        /// 清除缓存中所有项
        /// </summary>
        public  void ClearAll()
        {
            IDictionaryEnumerator enumerator = _cache.GetEnumerator();
            ArrayList list = new ArrayList();
            while (enumerator.MoveNext())
            {
                list.Add(enumerator.Key);
            }
            foreach (string str in list)
            {
                _cache.Remove(str);
            }
            list.Clear();
        }

      #endregion


      #region 类方法
        /// <summary>
        /// 向缓存中加入内容
        /// </summary>
        /// <param name="key">键值</param>
        /// <param name="obj">键值对应内容</param>
        public  void Insert(string key, object obj)
        {
            Insert(key, obj, null, _minutes);
        }

        /// <summary>
        /// 向缓存中加入内容,并设置缓存过期时间(秒为单位)
        /// </summary>
        /// <param name="key">键值</param>
        /// <param name="obj">键值对应内容</param>
        /// <param name="seconds">过期时间(单位:分钟)</param>
        public  void Insert(string key, object obj, int minutes)
        {
            Insert(key, obj, null, minutes);
        }

        /// <summary>
        /// 向缓存中加入内容,并设置此缓存项所依赖的缓存中项(依赖项变化时,自动删除此缓存项)
        /// </summary>
        /// <param name="key">键值</param>
        /// <param name="obj">键值对应内容</param>
        /// <param name="dep">依赖项</param>
        public  void Insert(string key, object obj, CacheDependency dep)
        {
            Insert(key, obj, dep, _minutes);
        }

        /// <summary>
        /// 向缓存中加入内容
        /// </summary>
        /// <param name="key">键值</param>
        /// <param name="obj">键值对应内容</param>
        /// <param name="seconds">过期时间(单位:分钟)</param>
        /// <param name="priority">缓存中项的优先级(枚举值)</param>
        public  void Insert(string key, object obj, int minutes, CacheItemPriority priority)
        {
            Insert(key, obj, null, minutes, priority);
        }

        /// <summary>
        /// 向缓存中加入内容
        /// </summary>
        /// <param name="key">键值</param>
        /// <param name="obj">键值对应内容</param>
        /// <param name="dep">依赖项</param>
        /// <param name="minute">过期时间(单位:分钟)</param>
        public void Insert(string key, object obj, CacheDependency dep, int minutes)
        {
            Insert(key, obj, dep, minutes, CacheItemPriority.Normal);
        }

        /// <summary>
        /// 向缓存中加入内容
        /// </summary>
        /// <param name="key">键值</param>
        /// <param name="obj">键值对应内容</param>
        /// <param name="dep">依赖项</param>
        /// <param name="minutes">过期时间(单位:分钟)</param>
        /// <param name="priority">缓存中项的优先级(枚举值)</param>
        public  void Insert(string key, object obj, CacheDependency dep, int minutes, CacheItemPriority priority)
        {
            if (obj != null)
            {
                _cache.Insert(key, obj, dep,DateTime.Now.AddMinutes(minutes),TimeSpan.Zero, priority, null);
            }
        }

        /// <summary>
        /// 向缓存中加入内容,并设置过期时间为永不过期
        /// </summary>
        /// <param name="key">键值</param>
        /// <param name="obj">键值对应内容</param>
        public  void Max(string key, object obj)
        {
            Max(key, obj, null);
        }
        /// <summary>
        /// 向缓存中加入内容,并设置过期时间为永不过期,但是如果
        /// 依赖项发生变化,则自动清除缓存内容,在服务器释放内在时,可能会被清除
        /// </summary>
        /// <param name="key">键值</param>
        /// <param name="obj">键值对应内容</param>
        /// <param name="dep">依赖项</param>
        public  void Max(string key, object obj, CacheDependency dep)
        {
            if (obj != null)
            {
                _cache.Insert(key, obj, dep, DateTime.MaxValue, TimeSpan.Zero, CacheItemPriority.AboveNormal, null);
            }
        }

        /// <summary>
        /// 向缓存中加入内容,并设置过期时间为永不过期,
        /// 在服务器释放内存时,不会被清除(重启IIS会被清除)
        /// </summary>
        /// <param name="key">键值</param>
        /// <param name="obj">键值对应内容</param>
        public  void Permanent(string key, object obj)
        {
            Permanent(key, obj, null);
        }

        /// <summary>
        /// 向缓存中加入内容,并设置过期时间为永不过期,但是如果
        /// 依赖项发生变化,则自动清除缓存内容,
        /// 在服务器释放内存时,不会被清除(重启IIS会被清除)
        /// </summary>
        /// <param name="key">键值</param>
        /// <param name="obj">键值对应内容</param>
        /// <param name="dep">依赖项</param>
        public  void Permanent(string key, object obj, CacheDependency dep)
        {
            if (obj != null)
            {
                _cache.Insert(key, obj, dep, DateTime.MaxValue, TimeSpan.Zero, CacheItemPriority.NotRemovable, null);
            }
        }


        /// <summary>
        /// 清除缓存中符合正则表达式的项
        /// </summary>
        /// <param name="pattern">正则表达式</param>
        public  void RemoveByPattern(string pattern)
        {
            IDictionaryEnumerator enumerator = _cache.GetEnumerator();
            Regex regex = new Regex(pattern, RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase);
            while (enumerator.MoveNext())
            {
                if (regex.IsMatch(enumerator.Key.ToString()))
                {
                    _cache.Remove(enumerator.Key.ToString());
                }
            }
        }

        /// <summary>
        /// 设置缓存时间的基数值,不用缓存可设置为零
        /// </summary>
        /// <param name="cacheFactor">缓存基数</param>
        public  void ReSetFactor(int cacheFactor)
        {
            _minutes = cacheFactor;
        }
        #endregion

        #region ICache 成员


        public string StringRootPath
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        #endregion
    }
}

